package com.newture.lxz.controller;


import com.newture.lxz.controller.helper.Result;
import com.newture.lxz.errors.Errors;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.sql.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


@Controller
@RequestMapping("/lpr")
@Validated
public class LPRCalculator {
    @GetMapping("/getTerminal")
    @ResponseBody
    public Result getTerminal() {
        Connection con = this.getConnection();
        Statement sta = null;
        ResultSet re1 = null;
        ResultSet re2 = null;
        try {
            sta = con.createStatement();
            re1 = sta.executeQuery("select gmt_date_start from law_doc.ld_interbank_offered_rate limit 1");
            re1.next();
            String start = re1.getString(1);
            System.out.println(start);
            sta = con.createStatement();
            re2 = sta.executeQuery("select gmt_date_end from law_doc.ld_interbank_offered_rate order by id DESC limit 1");
            re2.next();
            String end = re2.getString(1);
            System.out.println(end);
            return Result.success(new String[]{start, end});
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            return Result.success("数据库名没有任何值");
        } finally {
            try {
                sta.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    @GetMapping("/lprcalc")
    @ResponseBody
    public Result lprcalc(
            @RequestParam(name = "day_start", required = true) String d1,
            @RequestParam(name = "day_end", required = true) String d2,
            @RequestParam(name = "amount_of_arrears", required = true) String arrears
    ) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH");
        Connection con = this.getConnection();
        Statement sta = null;
        try {
            Date dl = sdf.parse(d1);
            Date dr = sdf.parse(d2);
            int month_dl = Integer.parseInt(d1.substring(5, 7));
            int date_dl = Integer.parseInt(d1.substring(8, 10));
            int[] newDate = getNextDay(dl.getYear() + 1900, month_dl, date_dl);

            month_dl = newDate[1];
            date_dl = newDate[2];
            int year_dl = newDate[0];
            System.out.println(year_dl + " " + month_dl + " " + date_dl);
            int month_dr = Integer.parseInt(d2.substring(5, 7));
            int date_dr = Integer.parseInt(d2.substring(8, 10));
            newDate = getNextDay(dr.getYear() + 1900, month_dr, date_dr);
            int year_dr = newDate[0];
            month_dr = newDate[1];
            date_dr = newDate[2];
            //查找操作
            con = this.getConnection();
            sta = con.createStatement();
            ResultSet re1 = null;
            ResultSet re2 = null;
            ResultSet re3 = null;
            boolean nvoid1 = true;
            boolean nvoid2 = true;
            List<Ele> list = new ArrayList<Ele>();

            re1 = sta.executeQuery(LPRCalculator.getQuerySentence(year_dl, month_dl));

            if (!re1.next()) {
                re1 = sta.executeQuery(LPRCalculator.getLastMonthQuerySentence(year_dl, month_dl));
                if (!re1.next()) {
                    return Result.success("左侧端点不在查找范围内");
                }
                list.add(new Ele(year_dl, month_dl, date_dl, re1.getDouble(1) / 100));
            } else {
                int dayl = re1.getInt(2);
                double ratel = re1.getDouble(1);
                list.add(new Ele(year_dl, month_dl, date_dl, re1.getDouble(1) / 100));
                if (dayl > date_dl) {
                    re1 = sta.executeQuery(LPRCalculator.getLastMonthQuerySentence(year_dl, month_dl));
                    if (!re1.next()) {
                        return Result.success("左端点不在查找范围内");
                    }

                    list.remove(list.size() - 1);
                    list.add(new Ele(year_dl, month_dl, date_dl, re1.getDouble(1) / 100));
                    list.add(new Ele(year_dl, month_dl, dayl, ratel / 100));
                }
            }

            sta = con.createStatement();
            re2 = sta.executeQuery(LPRCalculator.getQuerySentence(year_dl, month_dr));

            //讨论右侧断电
            if (!re2.next()) {
                re2 = sta.executeQuery(LPRCalculator.getLastMonthQuerySentence(year_dr, month_dr));
                if (!re2.next()) {
                    return Result.success("右侧端点不在查找范围内");
                }
                list.add(new Ele(year_dr, month_dr, date_dr, re2.getDouble(1) / 100));
            } else {
                int dayr = re2.getInt(2);
                double rater = re2.getDouble(1);
                if (date_dr < re2.getInt(2)) {
                    re2 = sta.executeQuery(LPRCalculator.getLastMonthQuerySentence(year_dr, month_dr));
                    if (!re2.next()) {
                        return Result.success("右端点不在查找范围内");
                    }
                    list.add(new Ele(year_dr, month_dr, date_dr, re2.getDouble(1) / 100));
                } else {
                    list.add(new Ele(year_dr, month_dr, dayr, rater / 100));
                    list.add(new Ele(year_dr, month_dr, date_dr, rater / 100));
                }
            }
            sta = con.createStatement();

            //下面开始查找左右端点之间的部分
            for (int i = 0; i <= list.size() - 2; i++) {
                Ele e1 = list.get(i);
                Ele e2 = list.get(i + 1);
                if (Ele.getMonthDifference(e1, e2) >= 2) {
                    Ele e = Ele.addOneMonth(e1);
                    re3 = sta.executeQuery(LPRCalculator.getQuerySentence(e.getYear(), e.getMonth()));
                    if (!re3.next()) {
                        return Result.success("这段时间间有数据缺失");
                    }
                    list.add(i + 1, new Ele(e.getYear(), e.getMonth(), re3.getInt(2), re3.getDouble(1) / 100));
                }
            }
            if (list.size() == 3 && list.get(0).getMonth() == list.get(2).getMonth() && list.get(1).getDay() > list.get(2).getDay()) {
                list.remove(1);
            }
            double interest = 0;
            //然后计算利息
            for (int i = 0; i < list.size(); i++) {
                Ele e = list.get(i);
                System.out.println(e.getYear() + "   " + e.getMonth() + " " + e.getDay() + "   " + e.getRate());
            }
            for (int i = 0; i <= list.size() - 2; i++) {
                int days_num = Ele.getDaysDifference(list.get(i), list.get(1 + i));
                if (i == list.size() - 2) {
                    days_num += 1;
                }

                double r = list.get(i).getRate();
                interest += days_num * r * Double.parseDouble(arrears) / 360;
            }
            BigDecimal b = new BigDecimal(interest);
            interest = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            return Result.success(interest);

        } catch (ParseException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            try {
                if (sta != null) {
                    sta.close();
                }
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return Result.failure(Errors.UNKNOWN_ERROR.name());
    }

    public Connection getConnection() {
        Connection conn = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try {

            conn = DriverManager.getConnection("jdbc:mysql://localhost:3307/law_doc", "root", "MyPass@123");
            System.out.println("数据库链接成功");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return conn;
    }

    public static String getQuerySentence(int y, int mon) {
        return "select rate,day(gmt_date_start) from law_doc.ld_interbank_offered_rate where year(gmt_date_start)="
                + y + " and month(gmt_date_start)=" + mon;
    }


    public static String getLastMonthQuerySentence(int y, int mon) {
        int month = mon;
        int year = y;
        if (mon == 1) {
            month = 12;
            year -= 1;
        } else {
            month -= 1;
        }
        return "select rate,day(gmt_date_start) from law_doc.ld_interbank_offered_rate where year(gmt_date_start)="
                + year + " and month(gmt_date_start)=" + month;
    }

    public static String getNextMonthQuerySentence(int y, int mon) {
        int month = mon;
        int year = y;
        if (mon + 1 >= 12) {
            month = 1;
            year += 1;
        } else {
            month += 1;
        }
        return "select rate,day(gmt_date_start) from law_doc.ld_interbank_offered_rate where year(gmt_date_start)="
                + year + " and month(gmt_date_start)=" + month;
    }

    public int[] getNextDay(int currentYear, int currentMonth, int currentDay) {
        Integer[] oddMonths = new Integer[]{1, 3, 5, 7, 8, 10};
        Integer[] evenMonths = new Integer[]{4, 6, 9, 11};
        int nextDay = 0;
        int nextMonth = 0;
        int nextYear = 0;
        int[] newDate = new int[3];

        if (currentDay == 31) {

            if (Arrays.asList(oddMonths).contains(currentMonth)) {
                nextDay = 1;
                nextMonth = getNextMonth(currentMonth);
                nextYear = currentYear;
            } else if (currentMonth == 12) {
                nextMonth = 1;
                nextDay = 1;
                nextYear = currentYear + 1;
            }

        } else if (Arrays.asList(evenMonths).contains(currentMonth) && currentDay == 30) {
            nextDay = 1;
            nextMonth = getNextMonth(currentMonth);
            nextYear = currentYear;
        } else if (currentDay == 29 && currentMonth == 2) {
            nextDay = 1;
            nextMonth = currentMonth + 1;
            nextYear = currentYear;
        } else if (currentDay == 28 && currentMonth == 2) {
            if ((currentYear % 4 == 0 && currentYear % 100 != 0) || currentYear % 400 == 0) {
                nextDay = 29;
                nextMonth = 2;
                nextYear = currentYear;
            } else {
                nextDay = 1;
                nextMonth = 3;
                nextYear = currentYear;
            }
        } else {
            nextMonth = currentMonth;
            nextDay = currentDay + 1;
            nextYear = currentYear;
        }
        newDate[0] = nextYear;
        newDate[1] = nextMonth;
        newDate[2] = nextDay;

        return newDate;
    }

    public int getNextMonth(int currentMonth) {
        if (currentMonth == 12) {
            return 1;
        } else {
            return currentMonth + 1;
        }
    }

    public static void main(String[] args) {
        //Integer []oddMonths=new Integer[]{1,3,5,7,8,10,12};
        //int []evenMonths=new int[]{4,6,9,11};
        //List list= Arrays.asList(oddMonths);
        int currentDay = 31;
        int currentMonth = 11;
        int iter = currentMonth * 69905 ^ 759362;
        boolean flag = !(iter % 16 == 0);
        do {
            iter = iter / 16;
            flag = flag | (iter % 16 == 0);
        } while (iter > 0);
        System.out.println(!flag);
    }
}
